﻿// <copyright file="ReportElement.cs" company="Todd Aspeotis">
//  Copyright © 2011 Todd Aspeotis
// </copyright>

namespace LocalReportsEngine.ReportDefinitionElements
{
    using System;
    using System.Collections.Generic;
    using System.Xml;
    using System.Xml.Serialization;
    using LocalReportsEngine.ExtensionMethods;

    /// <summary>
    /// Provides a representation of the Report element.
    /// </summary>
    public class ReportElement
    {
        /// <summary>
        /// Prevents a default instance of the ReportElement class from being created.
        /// </summary>
        private ReportElement()
        {
        }

        /// <summary>
        /// Gets the name of the report definition element this class represents.
        /// </summary>
        public static string ElementName
        {
            get { return "Report"; }
        }

        /// <summary>
        /// Gets or sets the collection of DataSet child elements.
        /// </summary>
        [XmlArray("DataSets")]
        [XmlArrayItem("DataSet")]
        public List<DataSetElement> DataSets { get; set; }

        /// <summary>
        /// Gets or sets the collection of DataSource child elements.
        /// </summary>
        [XmlArray("DataSources")]
        [XmlArrayItem("DataSource")]
        public List<DataSourceElement> DataSources { get; set; }

        /// <summary>
        /// Creates an instance of the class from the supplied report path.
        /// </summary>
        /// <param name="path">Path of the report file to instatiate from.</param>
        /// <returns>A new instance of the class loaded from <paramref name="path"/>.</returns>
        public static ReportElement Load(string path)
        {
            using (XmlReader reader = XmlReader.Create(path))
            {
                XmlAttributeOverrides overrides = CreateXmlAttributeOverrides(reader);

                if (overrides == null)
                {
                    return null;
                }

                XmlSerializer serializer = new XmlSerializer(typeof(ReportElement), overrides);
                return serializer.Deserialize(reader) as ReportElement;
            }
        }

        /// <summary>
        /// Creates an instance of the <see cref="XmlAttributeOverrides"/> class that can be used to
        /// serialize a Report report definition element from any report definition namespace.
        /// </summary>
        /// <param name="reader">The <see cref="XmlReader"/> to load the default namespace from.</param>
        /// <returns>
        /// An instance of <see cref="XmlAttributeOverrides"/>, or <see langword="null" /> if the
        /// default namespace could not be identified.
        /// </returns>
        private static XmlAttributeOverrides CreateXmlAttributeOverrides(XmlReader reader)
        {
            if (reader == null)
            {
                return null;
            }

            while (reader.Read())
            {
                if (reader.LocalName.SafeEquals(ElementName))
                {
                    break;
                }
            }

            if (reader.EOF)
            {
                return null;
            }

            XmlAttributes attributes = new XmlAttributes();
            attributes.XmlRoot = new XmlRootAttribute(ElementName);
            attributes.XmlRoot.Namespace = reader.NamespaceURI;
            XmlAttributeOverrides overrides = new XmlAttributeOverrides();
            overrides.Add(typeof(ReportElement), attributes);
            return overrides;
        }
    }
}
